package com.zheng.study.base.service.memcached;

import net.spy.memcached.MemcachedClient;
import net.spy.memcached.internal.OperationFuture;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.DisposableBean;

import java.util.Collection;
import java.util.Map;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

/**
 * newFile
 * ============================================================================
 * author : dzw
 * createDate:  2018/8/21 。
 * ============================================================================
 */
public class SpyMemcachedClient implements DisposableBean {

	private static Logger logger = LoggerFactory.getLogger(SpyMemcachedClient.class);
	private MemcachedClient memcachedClient;
	private long shutdownTimeout = 2500L;
	private long updateTimeout = 2500L;

	public SpyMemcachedClient() {
	}

	public <T> T get(String key) {
		try {
			return (T) this.memcachedClient.get(key);
		} catch (RuntimeException var3) {
			this.handleException(var3, key);
			return null;
		}
	}

	public <T> Map<String, T> getBulk(Collection<String> keys) {
		try {
			return (Map<String, T>) this.memcachedClient.getBulk(keys);
		} catch (RuntimeException var3) {
			this.handleException(var3, StringUtils.join(keys, ","));
			return null;
		}
	}

	public void set(String key, int expiredTime, Object value) {
		this.memcachedClient.set(key, expiredTime, value);
	}

	public boolean safeSet(String key, int expiration, Object value) {
		OperationFuture future = this.memcachedClient.set(key, expiration, value);

		try {
			return (Boolean)future.get(this.updateTimeout, TimeUnit.MILLISECONDS);
		} catch (Exception var6) {
			future.cancel(false);
			return false;
		}
	}

	public void delete(String key) {
		this.memcachedClient.delete(key);
	}

	public boolean safeDelete(String key) {
		OperationFuture future = this.memcachedClient.delete(key);

		try {
			return (Boolean)future.get(this.updateTimeout, TimeUnit.MILLISECONDS);
		} catch (Exception var4) {
			future.cancel(false);
			return false;
		}
	}

	public long incr(String key, int by, long defaultValue) {
		return this.memcachedClient.incr(key, by, defaultValue);
	}

	public long decr(String key, int by, long defaultValue) {
		return this.memcachedClient.decr(key, by, defaultValue);
	}

	public Future<Long> asyncIncr(String key, int by) {
		return this.memcachedClient.asyncIncr(key, by);
	}

	public Future<Long> asyncDecr(String key, int by) {
		return this.memcachedClient.asyncDecr(key, by);
	}

	private void handleException(Exception e, String key) {
		logger.warn("spymemcached client receive an exception with key:" + key, e);
	}

	public void destroy() throws Exception {
		if (this.memcachedClient != null) {
			this.memcachedClient.shutdown(this.shutdownTimeout, TimeUnit.MILLISECONDS);
		}
	}

	public MemcachedClient getMemcachedClient() {
		return this.memcachedClient;
	}

	public void setMemcachedClient(MemcachedClient memcachedClient) {
		this.memcachedClient = memcachedClient;
	}

	public void setUpdateTimeout(long updateTimeout) {
		this.updateTimeout = updateTimeout;
	}

	public void setShutdownTimeout(long shutdownTimeout) {
		this.shutdownTimeout = shutdownTimeout;
	}

	public long incr(String key, int by, long def, int exp) {
		return this.memcachedClient.incr(key, by, def, exp);
	}
}
